package cn.hyatt.auth.service.impl;

import cn.hyatt.auth.dto.systemRole.SystemRoleFindDto;
import cn.hyatt.auth.dto.systemRole.SystemRoleSaveDto;
import cn.hyatt.auth.dto.systemRole.SystemRoleUpdateDto;
import cn.hyatt.auth.dto.systemRole.SystemRoleVo;
import cn.hyatt.auth.entity.SystemRole;
import cn.hyatt.auth.event.SystemRoleEvent;
import cn.hyatt.auth.mapper.SystemRoleMapper;
import cn.hyatt.auth.service.SystemRoleMenuService;
import cn.hyatt.auth.service.SystemRoleService;
import cn.hyatt.common.exception.BusinessException;
import cn.hyatt.common.utils.ValidationUtil;
import cn.hyatt.core.utils.PageUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

/**
 * 系统角色-服务实现
 *
 * @author hyatt
 */
@Slf4j
@Service
@Primary
@AllArgsConstructor
public class SystemRoleServiceImpl extends ServiceImpl<SystemRoleMapper, SystemRole> implements SystemRoleService {

    private ApplicationEventPublisher publisher;
    private SystemRoleMenuService systemRoleMenuService;

    @Override
    public List<SystemRole> findByList(SystemRoleFindDto dto) {
        return baseMapper.findByList(dto);
    }

    @Override
    public IPage<SystemRole> findByPage(SystemRoleFindDto dto) {
        return baseMapper.findByPage(PageUtil.page(dto), dto);
    }

    @Override
    public List<SystemRole> findByUserId(Long userId) {
        return baseMapper.findByUserId(userId);
    }

    @Override
    @Transactional
    public void save(SystemRoleSaveDto dto) {
        // Copy 属性
        SystemRole entity = new SystemRole();
        BeanUtils.copyProperties(dto, entity);
        // 插入数据
        baseMapper.insert(entity);
        // 保存关联菜单
        if (!dto.getMenuIds().isEmpty()) {
            systemRoleMenuService.saveRoleMenus(entity.getId(), dto.getMenuIds());
        }

        // 发布事件
        publisher.publishEvent(new SystemRoleEvent.Save(entity));
    }

    @Override
    @Transactional
    public void update(Long id, SystemRoleUpdateDto dto) {
        // 获取修改对象
        Optional<SystemRole> optional = getOptById(id);
        SystemRole entity = optional.orElseThrow(
                () -> new BusinessException("找不到Id为(" + id + ")的数据")
        );
        // 保留旧实体记录
        SystemRole oldEntity = new SystemRole();
        BeanUtils.copyProperties(entity, oldEntity);
        // Copy 属性
        BeanUtils.copyProperties(dto, entity);
        // 验证数据内容
        ValidationUtil.validate(entity);
        // 按Id更新
        baseMapper.updateById(entity);
        // 保存关联菜单
        if (!dto.getMenuIds().isEmpty()) {
            systemRoleMenuService.deleteRoleMenus(entity.getId());
            systemRoleMenuService.saveRoleMenus(entity.getId(), dto.getMenuIds());
        }

        // 发布事件
        publisher.publishEvent(new SystemRoleEvent.Update(oldEntity, entity));
    }

    @Override
    @Transactional
    public void deleteById(Long id) {
        // 按Id删除
        baseMapper.deleteById(id);
        // 删除关联菜单
        systemRoleMenuService.deleteRoleMenus(id);
        // 发布事件
        publisher.publishEvent(new SystemRoleEvent.Delete(id));
    }

    @Override
    public SystemRoleVo toVo(SystemRole entity) {
        // Copy 属性
        SystemRoleVo vo = new SystemRoleVo();
        BeanUtils.copyProperties(entity, vo);

        return vo;
    }
}
